<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Object.defineProperty</title>
</head>
<body>
	
	
	<script>
		/*
			对象是由多个名/值对组成的无序的集合。对象中每个属性对应任意类型的值。
			定义对象可以使用构造函数或字面量的形式：
		 
			var obj = new Object;  // obj = {}
			obj.name = "张三";  // 添加描述
			obj.say = function(){};  // 添加行为
		*/
	  //除了以上添加属性的方式，还可以使用Object.defineProperty定义新属性或修改原有的属性。
		
		/**
		 * Object.defineProperty(obj, prop, descriptor)
		 * obj：必需。目标对象 
		 * prop：必需。需定义或修改的属性的名字
		 * descriptor：必需。目标属性所拥有的特性  数据描述符和存取器描述符
		 * 
		 * 返回值：传入函数的对象。即第一个参数obj
		 **//*
		var obj = {
			test: 'hello'
		}
		//  数据描述符
		Object.defineProperty(obj, 'test', {
			configurable:true | false,
//当且仅当该属性的 configurable 为 true 时，该属性描述符才能够被改变，同时该属性也能从对应的对象上被删除。默认为 false
			enumerable:true | false,
//当且仅当该属性的enumerable为true时，该属性才能够出现在对象的枚举属性中。默认为 false
			value:任意类型的值,
//该属性对应的值。可以是任何有效的 JavaScript 值（数值，对象，函数等）。默认为 undefined
			writable:true | false,
//当且仅当该属性的writable为true时，value才能被赋值运算符改变。默认为 false
		})
		*/
		/**
		 *  value: 设置属性的值
		 *	writable: 值是否可以重写。true | false
		 *	enumerable: 目标属性是否可以被枚举。true | false
		 *	configurable: 目标属性是否可以被删除或是否可以再次修改特性 true | false 
		 **/
		
		// 存取器描述符
		/**
		  var obj = {};
			Object.defineProperty(obj,"newKey",{
				get:function (){} | undefined,
一个给属性提供 getter 的方法，如果没有 getter 则为 undefined。
当访问该属性时，该方法会被执行，方法执行时没有参数传入，但是会传入this对象（由于继承关系，这里的this并不一定是定义该属性的对象）。				
			getter 是一种获得属性值的方法
				
				set:function (value){} | undefined
一个给属性提供 setter 的方法，如果没有 setter 则为 undefined。
当属性值修改时，触发执行该方法。该方法将接受唯一参数，即该属性新的参数值。				
				setter是一种设置属性值的方法。
				
				configurable: true | false
				enumerable: true | false
			});
		 
		 **/
		/*
		var obj = {};
		var initValue = 'hello';
		
		Object.defineProperty(obj,"newKey",{
			get:function (){
				//当获取值的时候触发的函数
				return initValue;    
			},
			set:function (value){
				//当设置值的时候触发的函数,设置的新值通过参数value拿到
				initValue = value;
			}
		});
		//获取值
		console.log( obj.newKey );  //hello

		//设置值
		obj.newKey = 'change value';

		console.log( obj.newKey ); //change value
		*/
		
	</script>
	
	<input type="text" class="test">
	
	<script>
		var txt = document.querySelector(".test");
		var person = {
			name: 'hsl'
		}
		
		txt.onchange = function(){
			person.name = this.value;
			console.log(person.name);
		}
		Object.defineProperty(person, 'name', {
			get:function(){
				return txt.value
			},
			set:function(newVal){
				txt.value = newVal
			}
		})
	</script>
	
	
	
</body>
</html>